﻿/*
-----------------------------------------------------------------------------
This source file is part of Cell Cloud.

Copyright (c) 2009-2012 Cell Cloud Team - cellcloudproject@gmail.com

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/

#ifndef CellPlatform_h
#define CellPlatform_h

#include "CellConfig.h"

namespace cell
{
/* 初始平台/编译器相关配置设置。
*/
#define CELL_PLATFORM_WIN32 1
#define CELL_PLATFORM_LINUX 2
#define CELL_PLATFORM_APPLE 3
#define CELL_PLATFORM_SYMBIAN 4
#define CELL_PLATFORM_IOS 5

#define CELL_COMPILER_MSVC 1
#define CELL_COMPILER_GNUC 2
#define CELL_COMPILER_BORL 3
#define CELL_COMPILER_WINSCW 4
#define CELL_COMPILER_GCCE 5

#define CELL_ENDIAN_LITTLE 1
#define CELL_ENDIAN_BIG 2

#define CELL_ARCHITECTURE_32 1
#define CELL_ARCHITECTURE_64 2

/* 判断编译器类型和版本。
*/
#if defined( __GCCE__ )
#   define CELL_COMPILER CELL_COMPILER_GCCE
#   define CELL_COMP_VER _MSC_VER
	//#	include <staticlibinit_gcce.h> // This is a GCCE toolchain workaround needed when compiling with GCCE 
#elif defined( __WINSCW__ )
#   define CELL_COMPILER CELL_COMPILER_WINSCW
#   define CELL_COMP_VER _MSC_VER
#elif defined( _MSC_VER )
#   define CELL_COMPILER CELL_COMPILER_MSVC
#   define CELL_COMP_VER _MSC_VER
#elif defined( __GNUC__ )
#   define CELL_COMPILER CELL_COMPILER_GNUC
#   define CELL_COMP_VER (((__GNUC__)*100) + \
	(__GNUC_MINOR__*10) + \
	__GNUC_PATCHLEVEL__)

#elif defined( __BORLANDC__ )
#   define CELL_COMPILER CELL_COMPILER_BORL
#   define CELL_COMP_VER __BCPLUSPLUS__
#   define __FUNCTION__ __FUNC__ 
#else
#   pragma error "No known compiler. Abort!"

#endif

/* 判断 __forceinline 有效性。
*/
#if CELL_COMPILER == CELL_COMPILER_MSVC
#   if CELL_COMP_VER >= 1200
#       define FORCEINLINE __forceinline
#   endif
#elif defined(__MINGW32__)
#   if !defined(FORCEINLINE)
#       define FORCEINLINE __inline
#   endif
#else
#   define FORCEINLINE __inline
#endif

/* 判断当前平台。
*/
#if defined( __SYMBIAN32__ ) 
#   define CELL_PLATFORM CELL_PLATFORM_SYMBIAN
#elif defined( __WIN32__ ) || defined( _WIN32 )
#   define CELL_PLATFORM CELL_PLATFORM_WIN32
#elif defined( __APPLE_CC__)
	// Device                                                     Simulator
	// Both requiring OS version 3.0 or greater
#   if __ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__ >= 30000 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 30000
#       define CELL_PLATFORM CELL_PLATFORM_IOS
#   else
#       define CELL_PLATFORM CELL_PLATFORM_APPLE
#   endif
#else
#   define CELL_PLATFORM CELL_PLATFORM_LINUX
#endif

/* 判断架构类型。*/
#if defined(__x86_64__) || defined(_M_X64) || defined(__powerpc64__) || defined(__alpha__) || defined(__ia64__) || defined(__s390__) || defined(__s390x__)
#   define CELL_ARCH_TYPE CELL_ARCHITECTURE_64
#else
#   define CELL_ARCH_TYPE CELL_ARCHITECTURE_32
#endif

// 通用的编译器警告信息定义。
#define CELL_QUOTE_INPLACE(x) # x
#define CELL_QUOTE(x) CELL_QUOTE_INPLACE(x)
#define CELL_WARN( x )  message( __FILE__ "(" QUOTE( __LINE__ ) ") : " x "\n" )

//----------------------------------------------------------------------------
// Windows 平台设置
#if CELL_PLATFORM == CELL_PLATFORM_WIN32

	// 如果客户程序里没有设置编译目标，则进行设置。
#	if defined( CELL_STATIC_LIB )
	// Linux 平台的编译器不支持 import/export 指令符号
#   	define _CellExport
#   	define _CellPrivate
#   else
#   	if defined( CELL_EXPORTS )
#       	define _CellExport __declspec( dllexport )
#   	else
#           if defined( __MINGW32__ )
#               define _CellExport
#           else
#       	    define _CellExport __declspec( dllimport )
#           endif
#   	endif
#   	define _CellPrivate
#	endif
	// Win32 编译器 DEBUG 模式下使用 _DEBUG 定义。
#   if defined(_DEBUG) || defined(DEBUG)
#       define CELL_DEBUG_MODE 1
#   else
#       define CELL_DEBUG_MODE 0
#   endif

	// 如果在是 MingW 上使用 GCC 3 则禁用 Unicode 支持。
	// GCC 4 不需要禁用。
#if defined(__MINGW32__)
# if CELL_COMP_VER < 400
#  if !defined(_STLPORT_VERSION)
#   include<_mingw.h>
#   if defined(__MINGW32_TOOLBOX_UNICODE__) || CELL_COMP_VER > 345
#    define CELL_UNICODE_SUPPORT 1
#   else
#    define CELL_UNICODE_SUPPORT 0
#   endif
#  else
#   define CELL_UNICODE_SUPPORT 1
#  endif
# else
#  define CELL_UNICODE_SUPPORT 1
# endif
#else
#  define CELL_UNICODE_SUPPORT 1
#endif

#endif // CELL_PLATFORM == CELL_PLATFORM_WIN32

//----------------------------------------------------------------------------
// Symbian 平台设置
#if CELL_PLATFORM == CELL_PLATFORM_SYMBIAN
#	define CELL_UNICODE_SUPPORT 1
#   define CELL_DEBUG_MODE 0
#   define _CellExport
#   define _CellPrivate
#	define CLOCKS_PER_SEC  1000
	// pragma def were found here: http://www.inf.pucrs.br/~eduardob/disciplinas/SistEmbarcados/Mobile/Nokia/Tools/Carbide_vs/WINSCW/Help/PDF/C_Compilers_Reference_3.2.pdf
#	pragma warn_unusedarg off
#	pragma warn_emptydecl off
#	pragma warn_possunwant off
#endif
//----------------------------------------------------------------------------
// Linux/Apple/Symbian 平台设置
#if CELL_PLATFORM == CELL_PLATFORM_LINUX || CELL_PLATFORM == CELL_PLATFORM_APPLE || CELL_PLATFORM == CELL_PLATFORM_IOS || CELL_PLATFORM == CELL_PLATFORM_SYMBIAN

	// 启用 GCC 符号 visibility
#   if defined( CELL_GCC_VISIBILITY )
#       define _CellExport  __attribute__ ((visibility("default")))
#       define _CellPrivate __attribute__ ((visibility("hidden")))
#   else
#       define _CellExport
#       define _CellPrivate
#   endif

	// 解决不同名称相同功能函数的宏定义。
#   define stricmp strcasecmp

	// Linux 系统编译器 DEBUG 模式下使用 DEBUG 定义。
#   ifdef DEBUG
#       define CELL_DEBUG_MODE 1
#   else
#       define CELL_DEBUG_MODE 0
#   endif

#if CELL_PLATFORM == CELL_PLATFORM_APPLE
#define CELL_PLATFORM_LIB "CellPlatform.bundle"
#elif CELL_PLATFORM == CELL_PLATFORM_IOS
#define CELL_PLATFORM_LIB "CellPlatform.a"
#else //CELL_PLATFORM_LINUX
#define CELL_PLATFORM_LIB "libCellPlatform.so"
#endif

	// 始终启用 Unicode 支持，如果 GCC 版本低可以禁用
#define CELL_UNICODE_SUPPORT 1

#endif

	//----------------------------------------------------------------------------

	//----------------------------------------------------------------------------
	// Endian 设置
	// 检查 BIG_ENDIAN 配置标识，正确设置 CELL_ENDIAN
#ifdef CELL_CONFIG_BIG_ENDIAN
#    define CELL_ENDIAN CELL_ENDIAN_BIG
#else
#    define CELL_ENDIAN CELL_ENDIAN_LITTLE
#endif

	// 固定 bit 宽的整数格式
	typedef unsigned int uint32;
	typedef unsigned short uint16;
	typedef unsigned char uint8;
	typedef int int32;
	typedef short int16;
	typedef char int8;
	// define uint64 type
#if CELL_COMPILER == CELL_COMPILER_MSVC
	typedef unsigned __int64 uint64;
	typedef __int64 int64;
#else
	typedef unsigned long long uint64;
	typedef long long int64;
#endif

// Crash Report 定义
#if CRASH_REPORT_SUPPORTED == 1
	#ifndef CELL_CRASH_REPORT
		#if CELL_PLATFORM == CELL_PLATFORM_WIN32 && CELL_ARCH_TYPE == CELL_ARCHITECTURE_32
			#define CELL_CRASH_REPORT
		#endif
	#endif // CELL_CRASH_REPORT
#else
	#ifdef CELL_CRASH_REPORT
		#undef CELL_CRASH_REPORT
	#endif
#endif

} // end namespace cell

#endif // CellPlatform_h
